import os
import sys
import subprocess
import random
import re
import requests
import uuid
import json
import time
from dotenv import load_dotenv
import dashscope
from dashscope import Generation
from src.processors.oss_uploader import upload_file_and_get_url
from src.processors.image_editor import process_image_edit
from pathlib import Path

# 加载.env文件中的环境变量
load_dotenv()

# 设置API密钥和基础URL
api_key = os.getenv("DASHSCOPE_API_KEY")
if api_key:
    dashscope.api_key = api_key
    dashscope.base_http_api_url = 'https://dashscope.aliyuncs.com/api/v1'

# 检查API密钥是否存在
if not api_key:
    raise ValueError("未找到DASHSCOPE_API_KEY环境变量，请检查.env文件配置")


def upload_image_to_oss(image_path):
    """
    将图片上传到OSS并返回可访问的URL
    
    Args:
        image_path (str): 图片路径
        
    Returns:
        str: OSS图片URL
    """
    try:
        # 使用现有的oss_uploader模块上传图片
        # 对于图片转视频任务，使用wanx2.1-kf2v-plus模型获取上传凭证
        oss_url = upload_file_and_get_url(api_key, "wan2.5-t2v-preview", image_path)
        print(f"图片上传成功，URL: {oss_url}")
        return oss_url
    except Exception as e:
        print(f"上传图片到OSS时出错: {str(e)}")
        # 如果上传失败，抛出异常而不是回退到Base64编码
        raise Exception(f"上传图片到OSS失败: {str(e)}")


def generate_prompt(image_path, text_content):
    """
    为女性图片生成视频提示词
    
    Args:
        image_path (str): 图片路径
        text_content (str): 文本内容
        
    Returns:
        tuple: (成功状态, 提示词)
    """
    try:
        # 使用固定的提示词加上随机的越南语台词
        vietnamese_phrases = [
            "Cùng theo dõi trận đấu hấp dẫn này nhé!",
            "Follow tôi để không bỏ lỡ những pha bóng đỉnh cao!",
            "Xem bóng đá cực đã, chỉ có tại kênh của tôi!",
            "Theo dõi ngay để cổ vũ cho đội bóng yêu thích!",
            "Bấm follow để cùng tôi theo dõi môn thể thao vua!",
            "Cập nhật tin tức bóng đá nhanh nhất, chỉ cần follow tôi!"
        ]
        
        # 随机选择一个越南语台词
        import random
        selected_phrase = random.choice(vietnamese_phrases)
        
        # 简化的提示词
        fixed_prompt = f"""
A passionate Vietnamese woman dynamically guides the viewer’s attention through the scene, reacting naturally to her surroundings and any visible objects (such as a football or the audience).
Her speech is clearly audible, with perfect lip-sync and emotional delivery — the viewer can clearly hear her warm and energetic Vietnamese voice.
She maintains direct eye contact with the viewer, smiles, and gestures expressively while speaking.
Her body movements and reactions feel spontaneous and realistic — for example, if a football is present, she may gently kick it, point at it, or look toward it with excitement.
The camera subtly follows her motion, creating an immersive and natural viewing experience.
She speaks in lively Vietnamese with clarity and enthusiasm, delivering the following line:
'{selected_phrase}'
"""

        print(f"使用固定提示词: {fixed_prompt}")
        return True, fixed_prompt
            
    except Exception as e:
        error_msg = f"生成提示词时出错: {str(e)}"
        print(error_msg)
        return False, error_msg


def generate_video_from_image_and_prompt(image_path, prompt_text, output_path, duration=10):
    """
    根据图片和提示词生成视频
    
    Args:
        image_path (str): 图片路径
        prompt_text (str): 视频生成提示词
        output_path (str): 输出视频路径
        duration (int): 视频时长(秒)
        
    Returns:
        tuple: (成功状态, 结果信息)
    """
    try:
        print(f"正在生成视频...")
        print(f"原始图片路径: {image_path}")
        print(f"提示词: {prompt_text}")
        print(f"目标时长: {duration}秒")
        
        # 先使用图片编辑功能生成符合要求的图片
        edit_prompt = "保留角色形象不变，只是更换衣服、裤子、鞋子的穿搭，要符合大众审美，然后背景要有足球相关的背景。"
        print(f"正在编辑图片，提示词: {edit_prompt}")
        
        # 生成编辑后图片的保存路径
        image_path_obj = Path(image_path)
        edited_image_path = image_path_obj.parent / f"{image_path_obj.stem}_edited_{uuid.uuid4().hex[:8]}{image_path_obj.suffix}"
        
        # 编辑图片
        edit_success, edit_result = process_image_edit(image_path, edit_prompt, output_path=str(edited_image_path))
        
        if not edit_success:
            error_msg = f"图片编辑失败: {edit_result}"
            print(error_msg)
            return False, error_msg
        
        print(f"图片编辑成功，编辑后的图片路径: {edit_result}")
        
        # 使用编辑后的图片路径作为视频生成的输入
        final_image_path = edit_result
        
        # 上传图片到OSS获取URL
        image_url = upload_image_to_oss(final_image_path)
        print(f"图片URL: {image_url}")
        
        # 简化视频生成提示词，专注于让图片动起来并让人物说话
        video_prompt = {prompt_text}

        # 使用与示例一致的API调用方式，使用img_url参数而不是first_frame_url/last_frame_url
        headers = {
            'X-DashScope-Async': 'enable',
            'X-DashScope-OssResourceResolve': 'enable',  # 添加此头部以支持oss://格式的URL
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json'
        }
        
        data = {
            "model": "wan2.5-i2v-preview",
            "input": {
                "prompt": video_prompt,
                "img_url": image_url
            },
            "parameters": {
                "duration": duration,
                "watermark": False,
                "seed": 1234,  # 10000以内随机整数
                "prompt_extend": True,
                "audio": True,
                "resolution": "480P"
            }
        }
        
        print("正在提交视频生成任务...")
        print(f"请求数据: {json.dumps(data, indent=2, ensure_ascii=False)}")
        
        response = requests.post(
            'https://dashscope.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis',
            headers=headers,
            json=data
        )
        
        print(f"响应状态码: {response.status_code}")
        print(f"响应内容: {response.text}")
        
        if response.status_code == 200:
            response_data = response.json()
            print(f"视频生成API完整响应: {response_data}")
            
            # 检查响应中是否包含任务ID
            if 'output' not in response_data or 'task_id' not in response_data['output']:
                error_msg = f"视频生成任务提交成功，但响应中未包含task_id字段。完整响应: {response_data}"
                print(error_msg)
                return False, error_msg
                
            task_id = response_data['output']['task_id']
            print(f"视频生成任务已提交，任务ID: {task_id}")
            
            # 等待任务完成
            video_url = None
            task_status = None
            max_attempts = 60  # 最多等待10分钟(60次*10秒)
            attempt = 0
            
            while attempt < max_attempts:
                print(f"正在等待视频生成完成... (尝试 {attempt+1}/{max_attempts})")
                time.sleep(10)  # 等待10秒后查询状态
                
                # 查询任务状态
                status_response = requests.get(
                    f'https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}',
                    headers={'Authorization': f'Bearer {api_key}'}
                )
                
                print(f"任务状态查询响应状态码: {status_response.status_code}")
                
                if status_response.status_code == 200:
                    status_data = status_response.json()
                    print(f"任务状态查询完整响应: {status_data}")
                    
                    if 'output' not in status_data or 'task_status' not in status_data['output']:
                        error_msg = f"任务状态查询成功，但响应中未包含task_status字段。完整响应: {status_data}"
                        print(error_msg)
                        return False, error_msg
                    
                    task_status = status_data['output']['task_status']
                    print(f"任务状态: {task_status}")
                    
                    # 检查任务是否失败
                    if task_status == 'FAILED':
                        error_message = status_data.get('output', {}).get('message', '未知错误')
                        error_code = status_data.get('output', {}).get('code', '未知错误码')
                        error_msg = f"视频生成失败: 错误码 {error_code}, 错误信息: {error_message}"
                        print(error_msg)
                        return False, error_msg
                    elif task_status == 'SUCCEEDED':
                        if 'video_url' not in status_data['output']:
                            error_msg = f"任务执行成功，但响应中未包含video_url字段。完整响应: {status_data}"
                            print(error_msg)
                            return False, error_msg
                            
                        video_url = status_data['output']['video_url']
                        print(f"视频生成完成，URL: {video_url}")
                        break
                    elif task_status == 'CANCELED':
                        error_msg = "视频生成任务已取消"
                        print(error_msg)
                        return False, error_msg
                else:
                    error_msg = f"查询任务状态失败，状态码: {status_response.status_code}，响应内容: {status_response.text}"
                    print(error_msg)
                
                attempt += 1
            
            if not video_url:
                error_msg = f"视频生成超时，最终任务状态: {task_status}"
                print(error_msg)
                return False, error_msg
            
            # 下载视频
            print("正在下载视频...")
            video_data = requests.get(video_url)
            if video_data.status_code == 200:
                with open(output_path, 'wb') as f:
                    f.write(video_data.content)
                print(f"视频已保存到: {output_path}")
                
                # 添加转码步骤
                transcoded_output_path = output_path.replace('.mp4', '_transcoded.mp4')
                print(f"正在转码视频以达到录制效果: {transcoded_output_path}")
                transcode_success = transcode_video_for_recording(output_path, transcoded_output_path)
                
                if transcode_success:
                    # 转码成功，删除原始文件，保留转码后的文件
                    os.remove(output_path)
                    # 重命名转码后的文件为原始文件名
                    os.rename(transcoded_output_path, output_path)
                    print(f"视频转码完成并已替换原始文件: {output_path}")
                else:
                    print("视频转码失败，保留原始视频文件")
                
                return True, output_path
            else:
                error_msg = f"下载视频失败，状态码: {video_data.status_code}，响应内容: {video_data.text}"
                print(error_msg)
                return False, error_msg
        else:
            error_msg = f"提交视频生成任务失败，状态码: {response.status_code}，响应内容: {response.text}"
            print(error_msg)
            return False, error_msg
            
    except Exception as e:
        error_msg = f"生成视频时出错: {str(e)}"
        print(error_msg)
        import traceback
        traceback.print_exc()
        return False, error_msg


def process_female_portrait_video(image_path, count, output_dir):
    """
    处理女性图片生成视频的完整流程
    
    Args:
        image_path (str): 图片路径
        count (int): 生成视频的数量
        output_dir (str): 输出目录
        
    Returns:
        tuple: (成功状态, 结果信息)
    """
    try:
        print("开始处理女性图片生成视频任务...")
        
        # 确保输出目录存在
        Path(output_dir).mkdir(parents=True, exist_ok=True)
        
        generated_videos = []
        for i in range(count):
            print(f"正在生成第{i+1}个视频...")
            
            # 1. 生成视频提示词
            success, result = generate_prompt(image_path, "足球相关内容")  # 使用已有的generate_prompt函数
            if not success:
                print(f"第{i+1}个视频提示词生成失败: {result}")
                continue
            
            prompt_text = result
            
            # 2. 生成文件名
            filename = f"female_video_{uuid.uuid4().hex[:8]}.mp4"
            output_path = os.path.join(output_dir, filename)
            
            # 3. 生成视频
            success, result = generate_video_from_image_and_prompt(image_path, prompt_text, output_path)
            if success:
                generated_videos.append(result)
                print(f"第{i+1}个视频生成成功: {result}")
            else:
                print(f"第{i+1}个视频生成失败: {result}")
        
        print("任务处理完成!")
        return True, generated_videos
        
    except Exception as e:
        error_msg = f"处理过程中出错: {str(e)}"
        print(error_msg)
        return False, error_msg


def transcode_video_for_recording(input_path, output_path):
    """
    为录制效果转码视频
    
    Args:
        input_path (str): 输入视频路径
        output_path (str): 输出视频路径
    """
    try:
        # 使用FFmpeg转码视频以达到"录制效果"
        cmd = [
            'ffmpeg',
            '-i', input_path,
            '-vf', 'setpts=PTS+0.05/TB,eq=brightness=0.02:contrast=1.03,boxblur=1:1',
            '-af', 'atempo=1.0',
            '-c:v', 'libx264',
            '-preset', 'medium',
            '-crf', '23',
            '-c:a', 'aac',
            '-b:a', '128k',
            '-movflags', '+faststart',
            '-map_metadata', '-1',
            '-y',
            output_path
        ]
        
        print(f"正在转码视频: {' '.join(cmd)}")
        result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8')
        
        if result.returncode == 0:
            print(f"视频转码成功: {output_path}")
            return True
        else:
            print(f"视频转码失败: {result.stderr}")
            return False
    except Exception as e:
        print(f"视频转码时出错: {str(e)}")
        return False
